home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1996
/
MacHack 1996.toast
/
Hacks
/
Hacks ’92
/
Scroll O Rama
/
SBar.c
next >
Wrap
C/C++ Source or Header
|
1992-06-19
|
16KB
|
609 lines
/* Scroll Bar Pattern CDEV */
/* by Jeff Walker */
/* © 1991 Walk Soft */
/* This Conrol Panel Device allows user to sellect and / or edit the */
/* pattern resource for the scroll bar pattern. */
#include "SBar.h"
/* Global variables are stored in GlobalStruct */
typedef struct
{
int thePat;
ControlHandle scrollBarH;
int DidAbout;
int IsActive;
} GlobalStruct, **GlobHandle;
/* Main: returns cDevValue. */
pascal long main(int message, int item, int numItems, int cPaneID,
EventRecord *theEvent, long cDevValue, DialogPtr CPDialog)
{
int itemType, patNumber, exitCode;
ControlHandle theSBH;
Handle itemH, tempH;
Rect itemRect;
char theChar;
Pattern blackPat;
Pattern greyPat;
PenState oldPen;
if (message == macDev)
return(RunOnAll);
else if (message == initDev)
{
if ((exitCode = InitCD(theSBH, &cDevValue,
CPDialog)) != NoError)
goto ErrorExit;
return(cDevValue);
}
/* End of initialization routine. */
if ((cDevValue != cdevUnset) && (cDevValue != ErrorState))
{
exitCode = NoError;
patNumber = (**((GlobHandle)cDevValue)).thePat;
theSBH = (**((GlobHandle)cDevValue)).scrollBarH;
if (theSBH == NilPtr)
{
exitCode = cdevResErr;
goto ErrorExit;
}
SetCtlValue(theSBH, patNumber);
switch (message)
{
case keyEvtDev:
if ((**((GlobHandle)cDevValue)).DidAbout < 1)
{
theChar = theEvent->message & charCodeMask;
if ((theChar == '\r') || (theChar == 3))
{
item = OKItem;
if ((exitCode = DoHit(patNumber, theSBH, item, numItems,
theEvent, cDevValue, CPDialog)) != NoError)
goto ErrorExit;
}
}
break;
case hitDev:
if ((exitCode = DoHit(patNumber, theSBH, item, numItems,
theEvent, cDevValue, CPDialog)) != NoError)
goto ErrorExit;
break;
case closeDev:
exitCode = NilPtr;
ErrorExit:
DisposeControl((**((GlobHandle)cDevValue)).scrollBarH);
DisposHandle((Handle)cDevValue);
cDevValue = (long)exitCode;
break;
case updateDev:
GetPenState(&oldPen);
patNumber = (**((GlobHandle)cDevValue)).thePat;
theSBH = (**((GlobHandle)cDevValue)).scrollBarH;
GetDItem(CPDialog, PatItem + numItems,
&itemType, &itemH, &itemRect);
FrameRect(&itemRect);
if ((exitCode = ShowFatPat(patNumber, CPDialog, numItems)) != NoError)
goto ErrorExit;
GetIndPattern(&blackPat, PatternID, 1);
GetIndPattern(&greyPat, PatternID, 24);
GetDItem(CPDialog, OKItem + numItems,
&itemType, &itemH, &itemRect);
PenSize(3, 3);
if ((**((GlobHandle)cDevValue)).IsActive)
PenPat(blackPat);
else
PenPat(greyPat);
InsetRect(&itemRect, -4, -4);
FrameRoundRect(&itemRect, 16, 16);
PenPat(blackPat);
break;
SetPenState(&oldPen);
case macDev:
return(RunOnAll);
break;
}
}
if (theEvent->what == mouseDown)
if ((**((GlobHandle)cDevValue)).DidAbout > 0)
(**((GlobHandle)cDevValue)).DidAbout--;
return(cDevValue);
}
/* InitCD: returns exitCode. Changes: cDevValue. Changes patNumber */
/* and the SBH and stores them in the GlobStruct. Initializes cdev. */
/* Used once. Calls: CopyPat. Is called by Main only. */
InitCD(ControlHandle theSBH, long *cDevValue, DialogPtr CPDialog)
{
int patNumber, myResFile;
Rect scrollRect;
Handle patNH, tempH;
PatHandle theLocalPat, theSysPat;
myResFile = CurResFile();
if ( (patNH = Get1Resource('patN', PatResID)) == NilPtr)
return(cdevResErr);
HLock(patNH);
patNumber = **patNH;
HUnlock(patNH);
if ( (patNumber < MinValue) || (patNumber > MaxValue))
return(cdevMemErr);
if ( (tempH = NewHandle(sizeof(GlobalStruct))) == NilPtr)
return (cdevMemErr);
(**((GlobHandle)tempH)).thePat = patNumber;
(**((GlobHandle)tempH)).DidAbout = FALSE;
(**((GlobHandle)tempH)).IsActive = TRUE;
scrollRect.top = NRCTBottom - ScrollWidth - 2;
scrollRect.left = NRCTLeft + 2;
scrollRect.bottom = NRCTBottom -2;
scrollRect.right = NRCTRight -2;
if (((**((GlobHandle)tempH)).scrollBarH = NewControl(CPDialog,
&scrollRect, NilPtr, 1, patNumber, MinValue, MaxValue,
scrollBarProc, NilPtr)) == NilPtr)
return (cdevResErr);
theSBH = (**((GlobHandle)tempH)).scrollBarH;
if (theSBH == NilPtr)
return(cdevMemErr);
SetCtlValue(theSBH, patNumber);
theLocalPat = GetPattern(SPatResID); /* get the local pattern */
if (theLocalPat == NilPtr)
return(cdevResErr);
HLock(theLocalPat);
UseResFile(SysResFile);
theSysPat = GetPattern(SPatResID); /* get the sys pattern */
if (theSysPat == NilPtr)
return(cdevResErr);
HLock(theSysPat);
CopyPat(*theSysPat, theLocalPat);
HUnlock(theLocalPat);
HUnlock(theSysPat);
UseResFile(myResFile);
*cDevValue = (long)tempH;
return(NoError);
}
/* DoHit: Handles HitDev messages. All user activity comes in the form */
/* of HitDev messages. Returns exitCode. Changes no parameters. */
/* Calls: DoDefault, DoOk, DoScroll, and ChangeFatPat, and showFatPat */
/* Is called by Main only. */
DoHit(int patNumber, ControlHandle theSBH, int item, int numItems,
EventRecord *theEvent, long cDevValue, DialogPtr CPDialog)
{
int myResFile, exitCode, itemType;
Rect itemRect, tempRect;
Handle itemH;
myResFile = CurResFile();
item -= numItems;
if ((**((GlobHandle)cDevValue)).DidAbout > 0)
(**((GlobHandle)cDevValue)).DidAbout --;
else
{
switch (item)
{
case DefaultItem:
if ((exitCode = DoDefault(&patNumber,theSBH,
numItems, CPDialog, myResFile)) != NoError)
return(exitCode);
break;
case OKItem:
if ((exitCode = DoOk(patNumber, theSBH,
numItems, CPDialog, myResFile)) != NoError)
return(exitCode);
(**((GlobHandle)cDevValue)).IsActive = FALSE;
break;
case ScrollBItem:
LightButtons(Active, numItems, CPDialog);
(**((GlobHandle)cDevValue)).IsActive = TRUE;
if ( (exitCode = DoScroll(&patNumber, theSBH,
theEvent, CPDialog)) != NoError)
return(exitCode);
if ((exitCode = WritePat(patNumber)) != NoError)
return(exitCode);
break;
case PatItem:
LightButtons(Active, numItems, CPDialog);
(**((GlobHandle)cDevValue)).IsActive = TRUE;
if ( (exitCode = ChangeFatPat(theEvent, CPDialog, numItems)) != NoError)
return(exitCode);
break;
case AboutItem: DoAbout();
(**((GlobHandle)cDevValue)).DidAbout = 2;
break;
default:
;
}
}
GetDItem(CPDialog, ScrollBItem + numItems,
&itemType, &itemH, &itemRect);
itemRect.bottom -= 1;
InvalRect(&itemRect);
if ((exitCode = ShowFatPat(patNumber, CPDialog, numItems)) != NoError)
return(exitCode);
(**((GlobHandle)cDevValue)).thePat = patNumber;
UpdateScroll();
return(NoError);
}
/* DoDefault: Writes the system's origonal pattern to the system pattern */
/* In other words, returns the system to its origonal state. */
/* returns: exitCode. Changes: patNumber. Calls: LightButtons, */
/* WritePat, StorePatNum. Is called by DoHit only. */
DoDefault(int *patNumber, ControlHandle theSBH,
int numItems, DialogPtr CPDialog, int myResFile)
{
int exitCode = NoError;
UseResFile(SysResFile);
*patNumber = SysPat + 1;
if ((exitCode = WritePat(*patNumber)) != NoError)
return (exitCode);
SetCtlValue(theSBH, *patNumber);
LightButtons(Dimmed, numItems, CPDialog);
UseResFile(myResFile);
if ((exitCode = WritePat(*patNumber)) != NoError)
return (exitCode);
if ((exitCode = StorePatNum(*patNumber)) != NoError)
return (exitCode);
return (exitCode);
}
/* DoOk: Handles the user hitting the OK button. It copies the pattern */
/* that the user has sellected to the system pattern. */
/* Returns: exitCode. Changes no parameters. Calls CopyPat and */
/* LightButtons. Is called by DoHit. */
DoOk(int patNumber, ControlHandle theSBH,
int numItems, DialogPtr CPDialog, int myResFile)
{
int exitCode = NoError;
PatHandle theLocalPat, theSysPat;
theLocalPat = GetPattern(SPatResID); /* get the local pattern */
if (theLocalPat == NilPtr)
return (cdevResErr);
HLock(theLocalPat);
UseResFile(SysResFile);
theSysPat = GetPattern(SPatResID); /* get the sys pattern */
if (theSysPat == NilPtr)
return (cdevResErr);
HLock(theSysPat);
CopyPat(*theLocalPat, theSysPat);
HUnlock(theLocalPat);
HUnlock(theSysPat);
LightButtons(Dimmed, numItems, CPDialog);
UseResFile(myResFile);
if ((exitCode = StorePatNum(patNumber)) != NoError)
return (exitCode);
return(exitCode);
}
DoAbout()
{
Rect tempRect;
int topEdge, leftEdge;
topEdge = NRCTTop + 14;
leftEdge = NRCTLeft + 40;
tempRect.top = NRCTTop;
tempRect.bottom = NRCTBottom - ScrollWidth - 2;
tempRect.left = NRCTLeft;
tempRect.right = NRCTRight;
EraseRect(&tempRect);
MoveTo(leftEdge, topEdge);
DrawString("\pScroll O Rama");
topEdge += 10;
MoveTo(leftEdge, topEdge);
DrawString("\pby Jeff Walker");
topEdge += 10;
MoveTo(leftEdge, topEdge);
DrawString("\p© 1991 Walk Soft");
topEdge += 10;
MoveTo(leftEdge, topEdge);
DrawString("\pWrite me at:");
topEdge += 10;
MoveTo(leftEdge, topEdge);
DrawString("\p37904 Summers");
topEdge += 10;
MoveTo(leftEdge, topEdge);
DrawString("\pLivonia, MI 48154");
while (!Button());
EraseRect(&tempRect);
InvalRect(&tempRect);
}
/* DoScroll: handles the scroll bar. Tracks where the thumb is moved to */
/* and calls the 'PAT#' pattern the corresponds. Uses SBCB, a code */
/* resource which TrackControl uses. Return exitCode. Changes: patNumber.*/
/* Calls no program functions. Is called by HitDev only. */
DoScroll(int *patNumber, ControlHandle theSBH, EventRecord *theEvent,
DialogPtr CPDialog)
{
Point thePoint;
short thePart;
ControlHandle theControl;
Handle callBackH;
thePoint = theEvent->where;
GlobalToLocal(&(thePoint));
thePart = FindControl(thePoint, CPDialog, &theControl);
if (theControl == NilPtr)
return(cdevMemErr);
switch (thePart)
{
case inThumb:
thePart = TrackControl (theSBH, thePoint, NilPtr);
*patNumber = GetCtlValue(theSBH);
break;
default:
if ((callBackH = Get1Resource('SBCB', ProcID)) == NilPtr)
return(cdevResErr);
HLock(callBackH);
thePart = TrackControl (theSBH, thePoint, *callBackH);
HUnlock(callBackH);
*patNumber = GetCtlValue(theSBH);
break;
}
return(NoError);
}
/* ChangeFatPat: changes the program's pattern when user edits in the */
/* fat-bits box. Returns exitCode. Changes the program's pattern. */
/* Calls no program functions. Is called by HitDev only. */
ChangeFatPat(EventRecord *theEvent, DialogPtr CPDialog, int numItems)
{
Point thePoint;
PatHandle thePatH;
int rowNum, bitNum;
int itemType;
Handle itemH;
Rect itemRect;
Point theOrigin;
thePoint = theEvent->where;
GlobalToLocal(&thePoint);
GetDItem(CPDialog, PatItem + numItems, &itemType, &itemH, &itemRect);
thePatH = (PatHandle)Get1Resource('PAT ', SPatResID);
if (thePatH == NilPtr)
return(cdevResErr);
HLock(thePatH);
thePoint.v -= itemRect.top;
thePoint.h -= itemRect.left;
rowNum = thePoint.v / 5;
if ((rowNum < 0) || (rowNum > 7))
return(cdevMemErr);
bitNum = thePoint.h / 5;
if ((bitNum < 0) || (bitNum > 7))
{
SysBeep(9);
return(cdevMemErr);
}
if ( BitTst(&((**thePatH)[0, rowNum]), bitNum) )
BitClr( &((**thePatH)[0, rowNum]), bitNum);
else
BitSet( &((**thePatH)[0, rowNum]), bitNum);
ChangedResource(thePatH);
WriteResource(thePatH);
HUnlock(thePatH);
return(NoError);
}
/* LightButtons: Changes the hiliting of the OK and Default buttons. */
/* Returns nothing. Changes no parameters. Calls no functions. Is */
/* called by DoHit. */
LightButtons(int hiliteVal, int numItems, DialogPtr CPDialog)
{
int itemType;
Handle itemH;
Rect itemRect;
PenState oldPen;
Pattern thePat, blackPat;
GetPenState(&oldPen);
ShowPen();
GetIndPattern(&thePat, PatternID, 24);
GetIndPattern(&blackPat, PatternID, 1);
GetDItem(CPDialog, OKItem + numItems,
&itemType, &itemH, &itemRect);
if (hiliteVal == Dimmed)
{
PenSize(3, 3);
PenPat(thePat);
InsetRect(&itemRect, -4, -4);
FrameRoundRect(&itemRect, 16, 16);
PenPat(blackPat);
}
else
{
PenSize(3, 3);
PenPat(blackPat);
InsetRect(&itemRect, -4, -4);
FrameRoundRect(&itemRect, 16, 16);
}
SetPenState(&oldPen);
GetDItem(CPDialog, OKItem + numItems,
&itemType, &itemH, &itemRect);
HiliteControl ((ControlHandle)itemH, hiliteVal);
GetDItem(CPDialog, DefaultItem + numItems,
&itemType, &itemH, &itemRect);
HiliteControl ((ControlHandle)itemH, hiliteVal);
}
/* CopyPat: Copies the data from one pattern to another. Usually from */
/* the program's pattern to the system pattern - except at initialization. */
/* Calls no function. Is called by: InitCD, DoHit, DoOk, and WritePat. */
CopyPat(PatPtr patSource, PatHandle patDest)
{
BlockMove(patSource, *patDest, sizeof(Pattern));
ChangedResource(patDest);
WriteResource(patDest);
}
/* WritePat: sellects the 'PAT#' pattern given by patNumber and copies it */
/* to the program pattern. Calls CopyPat. Is called by: DoHit and */
/* DoDefault. */
WritePat(int patNumber)
{
Pattern thePat;
PatHandle thePatH;
GetIndPattern(&thePat, PatternID, patNumber);
thePatH = GetPattern(SPatResID);
if (thePatH == NilPtr)
return(cdevResErr);
HLock(thePatH);
CopyPat(&thePat, thePatH);
HUnlock(thePatH);
return(NoError);
}
/* ShowFatPat: Displays in fat-bits form the pattern currently in the */
/* program. Returns exitCode. Changes no parameters. Calls nothing. */
/* Is called by main and DoHit. */
ShowFatPat(int patNumber, DialogPtr CPDialog, int numItems)
{
PatHandle thePatH;
int i;
int bitNum;
int itemType;
Handle itemH;
Rect itemRect;
PenState oldPen;
Point theOrigin;
GetPenState(&oldPen);
ShowPen();
PenMode(srcCopy);
PenSize(PenW, PenH);
GetDItem(CPDialog, PatItem + numItems, &itemType, &itemH, &itemRect);
InsetRect(&itemRect, 1, 1);
EraseRect(&itemRect);
theOrigin.v = itemRect.top;
theOrigin.h = itemRect.left;
thePatH = (PatHandle)Get1Resource('PAT ', SPatResID);
if (thePatH == NilPtr)
return(cdevResErr);
HLock(thePatH);
for (i= 0; i < 8; i++)
{
for (bitNum = 0; bitNum < 8; bitNum++)
{
if (BitTst(&((**thePatH)[0, i]), bitNum))
{
MoveTo(theOrigin.h + (bitNum) * 5,
theOrigin.v + (i * 5));
Line(0, 0);
}
}
}
HUnlock(thePatH);
SetPenState(&oldPen);
return(NoError);
}
/* StorePatNum: stores the current 'PAT#' pattern number in a resource of */
/* of type 'patN'. This allows for permanent storage of this variable. */
/* Returns exitCode. Changes no paramter. Calls no functions. Is called */
/* by DoDefault and DoOk. */
StorePatNum(int patNumber)
{
Handle patNH;
if ((patNH = Get1Resource('patN', PatResID)) == NilPtr)
return(cdevResErr);
HLock(patNH);
**patNH = patNumber;
ChangedResource(patNH);
WriteResource(patNH);
HUnlock(patNH);
return(NoError);
}
/* UpdateScroll: on systems < 7 it invalidates the scroll bar that */
/* belongs to the Control Panel. Is called by Main. */
UpdateScroll()
{
Rect sysScrollR;
sysScrollR.top = 1;
sysScrollR.left = 70;
sysScrollR.bottom = 249; /* bottom of control panel */
sysScrollR.right = 88;
InvalRect(&sysScrollR);
}